using System;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Test.BO.TestUtils;
using FireStarterModeller.Test;
using Habanero.Testability;
using NUnit.Framework;

namespace Firestarter.DB.Schema.Test.BO
{
    [TestFixture]
    public partial class TestDBKey
    {

        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = TestUtilsDBKey.CreateUnsavedValidDBKey();
            //---------------Assert Precondition----------------
            TestUtilsShared.AssertStringNotEmpty(dbKey.KeyName, "dbKey.KeyName");
            //---------------Execute Test ----------------------
            string actualToString = dbKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dbKey.KeyName, actualToString);
        }
        [Test]
        public void Test_ToString_KeyNameIsNull()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = TestUtilsDBKey.CreateUnsavedValidDBKey();
            dbKey.KeyName = "";
            //---------------Assert Precondition----------------
            TestUtilsShared.AssertStringEmpty(dbKey.KeyName, "dbKey.KeyName");
            //---------------Execute Test ----------------------
            string actualToString = dbKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual(dbKey.KeyID.ToString(), actualToString);
        }
        [Test]
        public void Test_ToString_KeyNameIsNull_KeyIdIsNull()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = TestUtilsDBKey.CreateUnsavedValidDBKey();
            dbKey.KeyName = "";
            dbKey.KeyID = null;
            //---------------Assert Precondition----------------
            TestUtilsShared.AssertStringEmpty(dbKey.KeyName, "dbKey.KeyName");
            Assert.IsNull(dbKey.KeyID);
            //---------------Execute Test ----------------------
            string actualToString = dbKey.ToString();
            //---------------Test Result -----------------------
            Assert.AreEqual("-unnamed key-", actualToString);
        }

        [Test]
        public void TestGetColumnInfo_NullWhenNoColumnsExist()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            DBColumn dbColumn = dbKey.GetColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbColumn);
        }

        [Test]
        public void TestGetColumnInfo_NullIfNotFound()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});

            DBColumn secondDBColumn = new DBColumn("TestColumn2");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = secondDBColumn});
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBColumn dbColumn = dbKey.GetColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbColumn);
        }

        [Test]
        public void TestGetColumnInfo_FindsExistingOne()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});

            const string testcolumn2 = "TestColumn2";
            DBColumn secondDBColumn = new DBColumn(testcolumn2);
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = secondDBColumn});
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBColumn dbColumn = dbKey.GetColumnInfo(testcolumn2);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dbColumn);
        }

        [Test]
        public void TestGetKeyColumnInfo_NullWhenNoColumnsExist()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.GetKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbKeyColumn);
        }

        [Test]
        public void TestGetKeyColumnInfo_NullIfNotFound()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});

            DBColumn secondDBColumn = new DBColumn("TestColumn2");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = secondDBColumn});
            string nonExistentColumn = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.GetKeyColumnInfo(nonExistentColumn);
            //---------------Test Result -----------------------
            Assert.IsNull(dbKeyColumn);
        }

        [Test]
        public void TestGetKeyColumnInfo_FindsExistingOne()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();

            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});

            const string testcolumn2 = "TestColumn2";
            DBColumn secondDBColumn = new DBColumn(testcolumn2);
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = secondDBColumn});
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.GetKeyColumnInfo(testcolumn2);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dbKeyColumn);
        }

        [Test]
        public void Test_AddNullColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            try
            {
                dbKey.AddColumnInfo(null);
                Assert.Fail("expected Err");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("dbColumn", ex.ParamName);
            }
        }

        [Test]
        public void Test_AddColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.AddColumnInfo(firstDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, dbKey.KeyColumns.Count);
            Assert.IsNotNull(dbKeyColumn);
            Assert.AreSame(firstDBColumn, dbKeyColumn.Column);
        }

        [Test]
        public void Test_AddSecondColumnInfo()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});
            DBColumn seondDBColumn = new DBColumn("TestColumn2");
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.AddColumnInfo(seondDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(2, dbKey.KeyColumns.Count);
            Assert.IsNotNull(dbKeyColumn);
            Assert.AreSame(seondDBColumn, dbKeyColumn.Column);
        }

        [Test]
        public void Test_AddColumnInfoTwice()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            DBColumn firstDBColumn = new DBColumn("TestColumn1");
            dbKey.KeyColumns.Add(new DBKeyColumn {Column = firstDBColumn});
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dbKey.KeyColumns.Count);
            //---------------Execute Test ----------------------
            DBKeyColumn dbKeyColumn = dbKey.AddColumnInfo(firstDBColumn);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, dbKey.KeyColumns.Count);
            Assert.IsNotNull(dbKeyColumn);
            Assert.AreSame(firstDBColumn, dbKeyColumn.Column);
        }

        [Test]
        public void Test_TableName_WhenTableNull_ShouldReturnEmptyString()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            //---------------Assert Precondition----------------
            Assert.IsNull(dbKey.Table);
            //---------------Execute Test ----------------------
            var actualTableName = dbKey.TableName;
            //---------------Test Result -----------------------
            Assert.IsEmpty(actualTableName);
        }

        [Test]
        public void Test_TableName_WhenTableSet_ShouldRetTableName()
        {
            //---------------Set up test pack-------------------
            DBKey dbKey = new DBKey();
            dbKey.Table = new DBTable(GetRandomString());
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dbKey.Table);
            //---------------Execute Test ----------------------
            var actualTableName = dbKey.TableName;
            //---------------Test Result -----------------------
            Assert.AreEqual(dbKey.Table.TableName, actualTableName);
        }

        private static string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
    }
}